package com.brokendust.client.api.module.pullpanel;

import com.brokendust.client.PixelEngine;
import com.brokendust.client.api.gui.Menu;
import com.brokendust.client.api.module.GUIComponent;
import com.brokendust.client.api.module.MouseListener;
import com.brokendust.client.api.module.PullPanelComponent;
import com.brokendust.client.api.module.button.ClickButton;
import com.brokendust.client.api.module.image.ImageShow;
import com.brokendust.client.api.module.item.ItemShow;
import com.brokendust.client.api.module.text.TextLabel;
import com.brokendust.client.api.module.textfield.TextField;
import com.brokendust.client.api.util.BasePosition;
import com.brokendust.client.api.util.image.ImageControl;
import com.brokendust.client.config.module.ComponentJson;
import com.brokendust.client.config.module.button.ClickButtonJson;
import com.brokendust.client.config.module.image.ImageShowJson;
import com.brokendust.client.config.module.item.ItemShowJson;
import com.brokendust.client.config.module.pullpanel.PullPanelJson;
import com.brokendust.client.config.module.text.TextLabelJson;
import com.brokendust.client.config.module.textfield.TextFieldJson;
import com.brokendust.client.config.module.util.ActionJson;
import com.brokendust.client.config.module.util.ButtonJson;
import com.brokendust.client.config.module.util.ConversionJson;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PullPanel extends AbstractGui implements MouseListener, GUIComponent {
    public int basePosition;
    public ResourceLocation image;
    public int guiWidth;
    public int guiHeight;
    public int objectWidth;
    public int objectHeight;
    public int x;
    public int y;
    public int position;
    public int startX;
    public int startY;
    public int displayWidth;
    public int displayHeight;
    public int moveWidth;
    public int moveHeight;
    public boolean switch_status;
    public int clickX;
    public int clickY;
    public boolean isClick;
    public int clickOutX;
    public int clickOutY;
    public List<ClickButtonJson> click_button_list;
    public List<TextFieldJson> text_field_json_list;
    public List<ImageShowJson> image_json_list;
    public List<TextLabelJson> text_json_list;
    public List<ItemShowJson> itemShowJsonList;
    public Map<String, PullPanelComponent> pullPanelComponentMap;
    Menu menu;

    public PullPanel(PullPanelJson pullPanelJson, int guiWidth, int guiHeight, Menu menu, int basePosition) {
        this.click_button_list = new ArrayList<ClickButtonJson>();
        this.text_field_json_list = new ArrayList<TextFieldJson>();
        this.image_json_list = new ArrayList<ImageShowJson>();
        this.text_json_list = new ArrayList<TextLabelJson>();
        this.itemShowJsonList = new ArrayList<ItemShowJson>();
        this.pullPanelComponentMap = new HashMap<String, PullPanelComponent>();
        this.basePosition = basePosition;
        this.guiWidth = guiWidth;
        this.guiHeight = guiHeight;
        this.menu = menu;
        this.image = ImageControl.getResourceLocation(pullPanelJson.getImage());
        this.objectWidth = pullPanelJson.getWidth();
        this.objectHeight = pullPanelJson.getHeight();
        this.displayWidth = pullPanelJson.getDisplayWidth();
        this.displayHeight = pullPanelJson.getDisplayHeight();
        this.startX = pullPanelJson.getStartX();
        this.startY = pullPanelJson.getStartY();
        this.position = pullPanelJson.getPosition();
        this.x = pullPanelJson.getX();
        this.y = pullPanelJson.getY();
        this.moveWidth = this.objectWidth - this.displayWidth;
        this.moveHeight = this.objectHeight - this.displayHeight;
        this.addPullPanelComponent(pullPanelJson);
        this.init();
    }

    public void init() {
        for (ClickButtonJson clickButtonJson : this.click_button_list) {
            ClickButton clickButton = new ClickButton(clickButtonJson, this.objectWidth, this.objectHeight, this.displayWidth, this.displayHeight);
            clickButton.setOnPress(clickButton1 -> {
                if (!clickButtonJson.getLeftList().isEmpty()) {
                    PixelEngine.pixelConnect.send("action", ConversionJson.writeJSON(new ActionJson(clickButtonJson.getLeftList())));
                }
                PixelEngine.pixelConnect.send("button", ConversionJson.writeJSON(new ButtonJson(clickButtonJson)));
                if (clickButtonJson.getTo_menu() != null && !clickButtonJson.getTo_menu().isEmpty()) {
                    this.menu.onClose();
                    PixelEngine.pixelConnect.send("ToMenu", clickButtonJson.getTo_menu());
                } else {
                    if (clickButtonJson.isClose()) {
                        this.menu.onClose();
                    }
                }
            });
            this.menu.addButton(clickButton);
            this.pullPanelComponentMap.put(clickButtonJson.getObject_name(), clickButton);
        }
        for (TextFieldJson textFieldJson : this.text_field_json_list) {
            TextField textField = new TextField(textFieldJson, this.objectWidth, this.objectHeight, this.displayWidth, this.displayHeight);
            this.menu.addButton(textField);
            this.pullPanelComponentMap.put(textFieldJson.getObject_name(), textField);
        }
        for (ImageShowJson imageShowJson : this.image_json_list) {
            ImageShow imageShow = new ImageShow(imageShowJson, this.objectWidth, this.objectHeight, this.displayWidth, this.displayHeight);
            this.pullPanelComponentMap.put(imageShowJson.getObject_name(), imageShow);
        }
        for (TextLabelJson textLabelJson : this.text_json_list) {
            TextLabel textLabel = new TextLabel(textLabelJson, this.objectWidth, this.objectHeight, this.displayWidth, this.displayHeight);
            this.pullPanelComponentMap.put(textLabelJson.getObject_name(), textLabel);
        }
        for (ItemShowJson itemShowJson : this.itemShowJsonList) {
            ItemShow itemShow = new ItemShow(itemShowJson, this.objectWidth, this.objectHeight, this.displayWidth, this.displayHeight);
            this.pullPanelComponentMap.put(itemShowJson.getObject_name(), itemShow);
        }
    }

    @Override
    public void upData(ComponentJson componentJson) {
        if (!(componentJson instanceof PullPanelJson)) {
            return;
        }
        PullPanelJson pullPanelJson = (PullPanelJson) componentJson;
        this.componentUpData(pullPanelJson);
    }

    @Override
    public void renderGUI(MatrixStack matrixStack, int mouseX, int mouseY, float particleTick, int guiX, int guiY) {
        int windowWidth = PixelEngine.minecraft.getWindow().getWidth();
        int windowHeight = PixelEngine.minecraft.getWindow().getHeight();
        Integer[] integers;
        if (this.basePosition < 10) {
            integers = BasePosition.getObjectPoint(guiX, guiY, this.guiWidth, this.guiHeight, this.displayWidth, this.displayHeight, this.x, this.y, this.position);
        } else {
            integers = BasePosition.getObjectPoint(guiX, guiY, windowWidth, windowHeight, this.displayWidth, this.displayHeight, this.x, this.y, this.position);
        }
        int mX = integers[0];
        int mY = integers[1];
        this.switch_status = (mouseX >= mX && mouseY >= mY && mouseX < mX + this.displayWidth && mouseY < mY + this.displayHeight);
        if (this.isClick) {
            int moveLengthX = this.clickX - mouseX + this.clickOutX;
            if (moveLengthX >= 0 && moveLengthX <= this.moveWidth) {
                this.startX = moveLengthX;
            }
            int moveLengthY = this.clickY - mouseY + this.clickOutY;
            if (moveLengthY >= 0 && moveLengthY <= this.moveHeight) {
                this.startY = moveLengthY;
            }
        }
        PixelEngine.minecraft.getTextureManager().bind(this.image);
        AbstractGui.blit(matrixStack, mX, mY, (float) this.startX, (float) this.startY, this.displayWidth, this.displayHeight, this.objectWidth, this.objectHeight);
        this.pullPanelComponentMap.forEach((s, pullPanelComponent) -> pullPanelComponent.renderPull(matrixStack, mouseX, mouseY, particleTick, mX - this.startX, mY - this.startY, mX, mY));
    }

    @Override
    public boolean mouseOn(double mouseX, double mouseY, int state) {
        if (this.switch_status) {
            this.clickX = (int) mouseX;
            this.clickY = (int) mouseY;
            this.isClick = true;
        }
        return false;
    }

    @Override
    public boolean mouseOff(double mouseX, double mouseY, int state) {
        if (this.isClick) {
            this.isClick = false;
            int moveLengthX = (int) (this.clickX - mouseX) + this.clickOutX;
            if (moveLengthX < 0) {
                moveLengthX = 0;
            }
            if (moveLengthX > this.moveWidth) {
                moveLengthX = this.moveWidth;
            }
            this.clickOutX = moveLengthX;
            int moveLengthY = (int) (this.clickY - mouseY) + this.clickOutY;
            if (moveLengthY < 0) {
                moveLengthY = 0;
            }
            if (moveLengthY > this.moveHeight) {
                moveLengthY = this.moveHeight;
            }
            this.clickOutY = moveLengthY;
        }
        return false;
    }

    @Override
    public boolean mouseScroll(double mouseX, double mouseY, double scrollDelta) {
        double scroll = this.startY - scrollDelta * 2.0;
        if (scroll > 0.0 && scroll <= this.moveHeight) {
            this.startY = (int) scroll;
            this.clickOutY = this.startY;
        }
        return true;
    }

    public void componentUpData(PullPanelJson pullPanelJson) {
        for (String type : pullPanelJson.getObjectList().keySet()) {
            String value = pullPanelJson.getObjectList().get(type);
            if (type.startsWith("Button")) {
                ClickButtonJson clickButtonJson = ClickButtonJson.readJSON(value);
                clickButtonJson.refreshSize();
                String object_id = clickButtonJson.getObject_name();
                if (!this.pullPanelComponentMap.containsKey(object_id)) {
                    continue;
                }
                this.pullPanelComponentMap.get(object_id).upData(clickButtonJson);
            } else if (type.startsWith("TextField")) {
                TextFieldJson textFieldJson = TextFieldJson.readJSON(value);
                textFieldJson.refreshSize();
                String object_id = textFieldJson.getObject_name();
                if (!this.pullPanelComponentMap.containsKey(object_id)) {
                    continue;
                }
                this.pullPanelComponentMap.get(object_id).upData(textFieldJson);
            } else if (type.startsWith("Image")) {
                ImageShowJson imageShowJson = ImageShowJson.readJSON(value);
                imageShowJson.refreshSize();
                String object_id = imageShowJson.getObject_name();
                if (!this.pullPanelComponentMap.containsKey(object_id)) {
                    continue;
                }
                this.pullPanelComponentMap.get(object_id).upData(imageShowJson);
            } else if (type.startsWith("Text")) {
                TextLabelJson textLabelJson = TextLabelJson.readJSON(value);
                String object_id = textLabelJson.getObject_name();
                if (!this.pullPanelComponentMap.containsKey(object_id)) {
                    continue;
                }
                this.pullPanelComponentMap.get(object_id).upData(textLabelJson);
            } else {
                if (!type.startsWith("Item")) {
                    continue;
                }
                ItemShowJson itemShowJson = ItemShowJson.readJSON(value);
                String object_id = itemShowJson.getObject_name();
                if (!this.pullPanelComponentMap.containsKey(object_id)) {
                    continue;
                }
                this.pullPanelComponentMap.get(object_id).upData(itemShowJson);
            }
        }
    }

    public void addPullPanelComponent(PullPanelJson pullPanelJson) {
        for (String type : pullPanelJson.getObjectList().keySet()) {
            String value = pullPanelJson.getObjectList().get(type);
            if (type.startsWith("Button")) {
                ClickButtonJson clickButtonJson = ClickButtonJson.readJSON(value);
                clickButtonJson.refreshSize();
                this.click_button_list.add(clickButtonJson);
            } else if (type.startsWith("TextField")) {
                TextFieldJson textFieldJson = TextFieldJson.readJSON(value);
                textFieldJson.refreshSize();
                this.text_field_json_list.add(textFieldJson);
            } else if (type.startsWith("Image")) {
                ImageShowJson imageShowJson = ImageShowJson.readJSON(value);
                imageShowJson.refreshSize();
                this.image_json_list.add(imageShowJson);
            } else if (type.startsWith("Text")) {
                TextLabelJson textLabelJson = TextLabelJson.readJSON(value);
                this.text_json_list.add(textLabelJson);
            } else {
                if (!type.startsWith("Item")) {
                    continue;
                }
                ItemShowJson itemShowJson = ItemShowJson.readJSON(value);
                this.itemShowJsonList.add(itemShowJson);
            }
        }
    }
}
